Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add api of registering storage #32

Merged
merged 2 commits into from
May 6, 2020

Conversation

wisererik
Copy link
Collaborator

What this PR does / why we need it:

Add api of registering storage, including:

  1. API validation of registering storage
  2. DB implementations of registering storage
  3. DriverManager.register_storage
  4. FakeDrver.register_storage

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes #

Special notes for your reviewer:

Release note:

# todo
# access_info['password'] = cryptor.encode(
# access_info['password'])
db.access_info_create(context, access_info)
Copy link
Contributor

@PravinRanjan10 PravinRanjan10 May 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason to messup the current architecture? I mean any specififc reason to add database creation, access logic to drivermanager?. In this way another thirdparty controller can not call our drivermanager.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's inevitable that the driver manager need to access the db, such as the driver or driver manager get the access info from db. we can not pass or save access info in memory because it contains the credential data.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to move db access to api layer first.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems no consistency mechanism here, need to consider the situation that access_info created in db successfully, but storage created failed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will concern about it.

this_session.commit()
return register_ref
if not values.get('storage_id'):
values['storage_id'] = uuidutils.generate_uuid()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want to maintain storage_id same in all tables. 'storage_id" should be the one returned from driver.
if driver is not returning 'storage_id' we should fail the registration in resource_manager itslef

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

storage_id should not be return by driver, it's a database id. for each creation operaion, uuid will be created if clients (such as api, driver manager, task manager) don't specify it in the model.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we discussed to move this to driver manager_ , if storage_id is not provided by driver, driver manager generates a uuid..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get your point here, it's a db implementation, the logic flow is if it doesn't contain id, it will generate, should not depend on the driver manager here. Uuid generation is also handled by driver manager

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine.. hope it is ok to have double checking here..

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, this is ok to have double check but not a good practice. Anything related to storage attrib/ID should be handled till driver/driver manager layer and should not be exposed above. If the client doesn't get storage_id, it should throw exception and not try to create one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no double check here, the code help caller to generate the uuid if the caller doesn't generate.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok..



def storage_create(context, values):
"""Add a storage device from the values dictionary."""
if not values.get('id'):
values['id'] = uuidutils.generate_uuid()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here. Let us not generate storage_id internally. this will create conflict between tables. We will use the storage_id returned by driver.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

.filter(Storage.id == storage_id) \
.first()
return storage_by_id
return _storage_get_get(context, storage_id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason why we do this logic in "_storage_get_get"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to support multiple pagenation and sorting. These codes are from openstack nova. it may accelerate our development

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, it's typo, has updated it.

# Check same access info from DB
access_info = copy.deepcopy(register_info)
vendor, model = access_info.pop('vendor'), access_info.pop('model')
db_access_info = db.access_info_get_all(context, sort_keys=['host'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

register_info is there as input this function. Why do we need to contact db and get access_info?
Also contacting db from driver layer is not according to our architecture..
plz consider

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with Pravin's

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

db.access_info_create(context, access_info)

storage['id'] = storage_id
storage = db.storage_create(context, storage)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

storage_create has to be from upper layer

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

raise exception.DolphinException(e)
except Exception as e:
msg = _('Failed to register device in driver :{0}'.format(e))
storage = driver.register_storage(ctxt, body)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to have the logic of validating storage object and creating DB entry for access_info and storage here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's already there, plz check the header of this function.

Copy link
Member

@NajmudheenCT NajmudheenCT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to change the tile of PR as " Refatoring Resgister API and adding driver manger code for registering"

'host': parameter_types.hostname_or_ip_address,
'port': parameter_types.tcp_udp_port,
'username': {'type': 'string', 'minLength': 1, 'maxLength': 255},
'password': {'type': 'string'},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any limitation for password? Min length, for example.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, has added.


return device_info
raise e
# except Exception as e:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unused codes here ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


def is_orm_value(obj):
"""Check if object is an ORM field."""
return IMPL.is_orm_value(obj)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need new line at end.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

host = Column(String(255))
port = Column(String(255))
username = Column(String(255))
password = Column(String(255))
Copy link
Member

@NajmudheenCT NajmudheenCT May 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acess_info would need 'vendor' and 'model' field, These information is required for the drivermanger to select driver.. please check

Copy link
Collaborator Author

@wisererik wisererik May 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not required here, they will be saved in Storage model

@wisererik wisererik force-pushed the register-storage branch 2 times, most recently from 086b2e7 to bec2b6b Compare May 5, 2020 10:06
.filter(Storage.id == storage_id) \
.first()
return storage_by_id
return _storage_get_get(context, storage_id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

this_session.commit()
return register_ref
if not values.get('storage_id'):
values['storage_id'] = uuidutils.generate_uuid()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we discussed to move this to driver manager_ , if storage_id is not provided by driver, driver manager generates a uuid..

NajmudheenCT
NajmudheenCT previously approved these changes May 5, 2020
Copy link
Member

@NajmudheenCT NajmudheenCT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

access_info_dict = copy.deepcopy(access_info)

# Remove unrelated query fields
access_info_dict.pop('username', None)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:
del_list = {'username', 'password', 'vendor', 'model'}
list(map(access_info_dict.delitem, filter(access_info_dict.contains, del_list)))
or
import operator
map(lambda x: operator.delitem(access_info_dict, x), del_list)

this_session.commit()
return register_ref
if not values.get('storage_id'):
values['storage_id'] = uuidutils.generate_uuid()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, this is ok to have double check but not a good practice. Anything related to storage attrib/ID should be handled till driver/driver manager layer and should not be exposed above. If the client doesn't get storage_id, it should throw exception and not try to create one.

return _storage_get_get(context, storage_id)


def _storage_get_get(context, storage_id, session=None):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this naming, storage_get_get? why can't it be simply get_storage or storage_get

hostname = Column(String(128))
username = Column(String(128))
password = Column(String(128))
storage_id = Column(String(36), primary_key=True)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to understand: Why is Storage_id the PK in access_info table? Should not this be FK or Composite? storage_id is ideally part of storage table

Copy link
Collaborator

@kumarashit kumarashit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
[Some comments maybe addressed/revisited later as part of issue]

Copy link
Collaborator

@sfzeng sfzeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kumarashit kumarashit merged commit 852f452 into sodafoundation:master May 6, 2020
skdwriting pushed a commit that referenced this pull request Mar 22, 2021
Delete trap redundant attribute in 3Par
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants